﻿#include "GLLInc.h"
#include "GLLObjSpcl.h"
#include "GLLVirtualWorld.h"
#include "GLLLevel.h"
#include "GLLMacro.h"
#include "GLLTheSystem.h"

#ifdef GLL_OGRE

namespace GLL
{
	inline
	Ogre::SceneManager* ObjectSpec::GetSceneManager()
	{
		return GetMgr()->_smOgre;
	}

	void ObjectSpec::SetPosition( const Position3Df& v)
	{
		if(NotLoaded()) return;
		if(!_node) return;
		_node->setPosition(v.x, v.y, v.z);
	}

	Position3Df ObjectSpec::GetPosition()
	{
		if(NotLoaded()) return Position3Df::ZERO();
		if(!_node) return Position3Df::ZERO();
		const Ogre::Vector3& vec = _node->getPosition();
		return Position3Df(vec.x, vec.y, vec.z);
	}

	void ObjectSpec::SetScale( const Size3Df& s)
	{
		if(NotLoaded()) return;
		if(!_node) return;
		_node->setScale(s.x, s.y, s.z);
	}

	Size3Df ObjectSpec::GetScale()
	{
		if(NotLoaded()) return Size3Df::ZERO();
		if(!_node) return Size3Df::ZERO();
		const Ogre::Vector3& vec = _node->getScale();
		return Size3Df(vec.x, vec.y, vec.z);
	}

	void ObjectSpec::SetRotation( const Axis3Df& a)
	{
		if(NotLoaded()) return;
		if(!_node) return;
		_node->pitch(Ogre::Degree(a.x));
		_node->yaw(Ogre::Degree(a.y));
		_node->roll(Ogre::Degree(a.z));
	}

	Axis3Df ObjectSpec::GetRotation()
	{
		if(NotLoaded()) return Axis3Df::ZERO();
		if(!_node) return Axis3Df::ZERO();
		const Ogre::Quaternion& q = _node->getOrientation();
		Axis3Df a(
			q.getPitch().valueDegrees(), 
			q.getYaw().valueDegrees(), 
			q.getRoll().valueDegrees()
			);
		return a;
	}

	ObjectSpec::ObjectSpec()
	{
		_node = 0;
	}

	ObjectSpec::~ObjectSpec()
	{
		assert(!_node);
	}

	void ObjectSpec::DoCreate()
	{
		_node = GetMgr()->_node->createChildSceneNode(Ogre::Vector3::ZERO);
	}

	void ObjectSpec::DoDestroy()
	{
		if(!_node) return;
		//销毁node
		LOCK_MUTEX(theWorld()->_renderMutex);
		GetMgr()->_node->removeAndDestroyChild(_node->getName());
		_node = 0;
	}

	void ObjectSpec::_PreLoad()
	{
		DoCreate();
	}

	void ObjectSpec::_PostUnload()
	{
		DoDestroy();
	}

	//-----------------------------------------------------------------------------
	void ObjectMesh::_DoLoad()
	{
		using namespace Ogre;

		//MeshPtr headMesh = MeshManager::getSingleton().load("ogrehead.mesh", GetMgr()->_strID);
		//unsigned short src, dest;
		//if (!headMesh->suggestTangentVectorBuildParams(VES_TANGENT, src, dest))
		//	headMesh->buildTangentVectors(VES_TANGENT, src, dest);

		//Ogre::Mesh::SubMeshIterator iter = headMesh->getSubMeshIterator();
		//while(iter.hasMoreElements())
		//{
		//	Ogre::SubMesh* sm = iter.getNext();
		//	const Ogre::String& mn = sm->getMaterialName();
		//}

		//// put an ogre head in the middle of the field
		try
		{
			GLL::String entityName = StrID();
			GLL::String modFile = GetPropVal<GLL::String>(OP_ModFile);
			if(GetSceneManager()->hasEntity(entityName))
			{
				bool MgrHas = GetMgr()->HasObject(GetID());
				GLL_BreakPoint;
			}
			_entity = GetSceneManager()->createEntity(entityName, modFile);			
		}
		catch(std::exception& e)
		{
			const char* pwhat = e.what();
			GLL_BreakPoint;
		}
	}

	void ObjectMesh::_PostLoad()
	{
		Object::_PostLoad();
		_node->attachObject(_entity);
	}

	void ObjectMesh::_DoUnload()
	{
		if(_entity){
			LOCK_MUTEX(theWorld()->_renderMutex);
			_node->detachObject(_entity);
			GetSceneManager()->destroyEntity(_entity);
			_entity = 0;
		}
	}

	ObjectMesh::~ObjectMesh()
	{
		if(_entity)
		{
			//_DoUnload();
			GLL_BreakPoint;
		}
	}

	ObjectMesh::ObjectMesh()
	{
		_entity = 0;
	}

	//-----------------------------------------------------------------------------

}//namespace





#endif GLL_OGRE
